import sys
import pygame

def getDistance(x1, y1, x2, y2):
    return abs(x1 - x2) + abs(y1-y2);

class FieldObject(object):
    def __init__(self, name, pictureFileName):
        self.name = name
        self.picture = pygame.image.load(pictureFileName)

#----------------------Items------------------------        
class Item(FieldObject):
    def __init__(self, name, pictureFileName):
        super(Item, self).__init__(name, pictureFileName)
        #FieldObject.__init__(self, name, pictureFileName)
        
    def use(self, target, user, targetTile, userTile, field):
        raise NotImplementedError('Method abstobj.abstmeth is pure virtual')
    
    def isDepleted(self):
        raise NotImplementedError('Method abstobj.abstmeth is pure virtual')
        
class HealingItem(Item):
    def __init__(self, name, pictureFileName, healingPower, charges):
        super(HealingItem, self).__init__(name, pictureFileName)
        #Item.__init__(self, name, pictureFileName)
        self.healingPower = healingPower
        self.charges = charges
        
    def use(self, target, user, field):
        targetY, targetX = field.getCreatureCoords(target)
        userY, userX = field.getCreatureCoords(user)
        if getDistance(targetX, targetY, userX, userY) > 1:
            return False
        else:
            target.hp = min(target.hpMax, target.hp + self.healingPower)
            self.charges -= 1
            return True
                
    def isDepleted(self):
        return self.charges == 0
    
class DamagingItem(Item):
    def __init__(self, name, pictureFileName, damage, charges):
        super(DamagingItem, self).__init__(name, pictureFileName)
        #Item.__init__(self, name, pictureFileName)
        self.damage = damage
        self.charges = charges
        
    def use(self, target, user, field):
        targetY, targetX = field.getCreatureCoords(target)
        userY, userX = field.getCreatureCoords(user)
        if field.checkLineOfSight(targetX, userX, targetY, userY):            
            target.hp = min(0, target.hp - self.damage)
            target.attacker = user
            field.updateCreature(target, user)
            self.charges -= 1
            return True
        else:
            return False
        
    def isDepleted(self):
        return self.charges == 0

#----------------------Creatures------------------------        
class Creep(FieldObject):
    def __init__(self, name, pictureFileName, hp, dmg, atkRange, expCost, moves, turnsToWait):
        super(Creep, self).__init__(name, pictureFileName)
        #FieldObject.__init__(self, name, pictureFileName)
        self.hp = hp
        self.hpMax = hp
        self.dmg = dmg
        self.atkRange = atkRange
        self.exp = 0
        self.expCost = expCost
        self.moves = moves
        self.turnsToWait = turnsToWait
        self.attacker = None
    def getDamage(self):
        return self.dmg
    def attack(self, target):
        target.hp -= self.getDamage()
class Player(FieldObject):
    def __init__(self, name, pictureFileName):
        super(Player, self).__init__(name, pictureFileName)
        self.hp = 200
        self.hpMax = 200
        self.dmg = 50
        self.inventory = []
        self.level = 1
        self.exp = 0
        self.atkRange = 3
        self.expCost = 100
        for i in range(0,16):
            self.inventory.append(None)
    def getDamage(self):
        return self.dmg
    def attack(self, target):
        target.hp -= self.getDamage()
    def hasInventorySpace(self):
        return True
    def pickItem(self, item):
        for i in range(0,16):
            if (self.inventory[i] is None):
                self.inventory[i] = item
                return True                
        return False
    def hasItem(self, itemIndex):
        return self.inventory[itemIndex] is not None
    def useItem(self, itemIndex, target, field):
            item = self.inventory[itemIndex]
            res = item.use(target, self, field)
            if item.isDepleted():
                self.inventory[itemIndex] = None
            return res
                
#----------------------Overlays------------------------
class Overlay(FieldObject):
    def __init__(self, name, pictureFileName, passable, visible):
        super(Overlay, self).__init__(name, pictureFileName)
        #FieldObject.__init__(self, name, pictureFileName)
        self.passable = passable
        self.visible = visible
